/*
* 使用立即执行函数模拟Es6暂时性死区，无法完全模拟暂时性死区，但是提前访问是 undefined ,执行new操作会报错
* */
// console.log(new Product())
var Product = (function () {
  function Product(name, uniPrice, number) {
    console.log('Object.getPrototypeOf(this)', Object.getPrototypeOf(this))
    console.log('Product.prototype', Product.prototype)
    // 判断函数是否使用new运算，不是则抛出错误
    if (Object.getPrototypeOf(this) !== Product.prototype) {
      throw new TypeError("calling Foo constructor without new is invalid");
    }
    
    this.name = name;
    this.uniPrice = uniPrice;
    this.number = number;
    Product.count++;
    
    // class 构造函数的访问器属性会在两个地方，一个在原型上，一个在实例上
    Object.defineProperty(this, "totalPrice", {
      get() {
        return this.number * this.uniPrice;
      },
      enumerable: false,
    })
  }
  
  Object.defineProperty(Product.prototype, "totalPrice", {
    get() {
      return this.number * this.uniPrice;
    }
  })
  
  Product.count = 0;
  
  // 原型上的方法不可枚举
  Object.defineProperty(Product.prototype, "increase", {
    enumerable: false,
    value: function () {
      console.log('this', this);
      console.log('Product.prototype.increase', Product.prototype.increase.prototype);
      // 原型上的方法不可通过new调用
      if(Object.getPrototypeOf(this) === Product.prototype.increase.prototype) {
        throw new TypeError("calling Foo constructor without new is invalid");
      }
      
      this.number++;
    }
  })
  
  return Product;
})();

const p = new Product('apple', 5, 5);
console.log(p)
